<?php

namespace app\models;

use app\helpers\Time;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\ActiveQuery;
use yii\db\JsonExpression;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;

/**
 * This is the model class for table "product".
 *
 * @property int $id id
 * @property string $title 标题
 * @property string $pic_url 图片
 * @property string $description 描述
 * @property float $price 默认价格
 * @property int $stock_num 库存
 * @property int $classify_id 分类id
 * @property int $created_at 创建时间
 * @property int $updated_at 修改时间
 * @property ProductAttr[] $productAttrs
 */
class Product extends \yii\db\ActiveRecord
{
    public $sku_desserts;
    public $select_values;

    const SCENARIO_CHANGE = 'change';

    public function behaviors()
    {
        return [
            [
                'class' => TimestampBehavior::class
            ]
        ];
    }

    /**
     * {@inheritdoc}
     */
    public static function tableName()
    {
        return 'product';
    }

    public function scenarios()
    {
        return array_merge(parent::scenarios(), [
            self::SCENARIO_CHANGE => [
                'title', 'pic_url', 'description', 'price', 'stock_num', 'classify_id', 'sku_desserts', 'select_values'
            ]
        ]);
    }

    /**
     * {@inheritdoc}
     */
    public function rules()
    {
        return [
            [['title', 'description', 'price', 'stock_num', 'classify_id', 'pic_url'], 'required'],
            [['price'], 'number'],
            [['stock_num', 'classify_id'], 'integer'],
            [['title', 'description'], 'string', 'max' => 255],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels()
    {
        return [
            'id' => Yii::t('app', 'ID'),
            'title' => Yii::t('app', 'Title'),
            'description' => Yii::t('app', 'Description'),
            'price' => Yii::t('app', 'Price'),
            'stock_num' => Yii::t('app', 'Stock Num'),
            'classify_id' => Yii::t('app', 'Classify ID'),
            'created_at' => Yii::t('app', 'Created At'),
            'updated_at' => Yii::t('app', 'Updated At'),
        ];
    }

    public function getClassify()
    {
        return $this->hasOne(Classify::class, ['id' => 'classify_id']);
    }

    public function getProductAttrs()
    {
        return $this->hasMany(ProductAttr::class, ['product_id' => 'id']);
    }

    public function getAttrValues()
    {
        return $this->hasMany(AttrValue::class, ['id' => 'attr_value_id'])
            ->via('productAttrs');
    }

    public function getAttrNames()
    {
        $attrValueIds = ArrayHelper::getColumn($this->productAttrs, ['attr_value_id']);

        return $this->hasMany(AttrName::class, ['id' => 'attr_name_id'])
            ->with([
                'attrValues' => function ($query) use ($attrValueIds) {
                    /** @var $query ActiveQuery */
                    $query->where(['in', 'id', $attrValueIds]);
                }
            ])
            ->via('productAttrs');
    }

    public function fields()
    {
        return array_merge(parent::fields(), [
            'pic_url_label' => function () {
                return str_replace('\\', '/', Url::to("@upload/{$this->pic_url}"));
            },
            'created_at' => function () {
                return Time::getTimeLabel($this->created_at);
            },
            'updated_at' => function () {
                return Time::getTimeLabel($this->updated_at);
            }
        ]);
    }

    public function extraFields()
    {
        return array_merge(parent::extraFields(), [
            'classify',
            'attrValues',
            'attrNames',
            'attrValueIds' => function () {
                return ArrayHelper::getColumn($this->productAttrs, ['attr_value_id']);
            }
        ]);
    }

    public function afterSave($insert, $changedAttributes)
    {
        parent::afterSave($insert, $changedAttributes);

        if ($this->scenario == self::SCENARIO_CHANGE) {
            $this->unlinkAll('attrValues', true);
            if ($this->select_values) {
                $attrValues = AttrValue::find()->with(['attrName'])->where(['in', 'id', $this->select_values])->all();
                foreach ($attrValues as $attrValue) {
                    $this->link('attrValues', $attrValue, ['attr_name_id' => $attrValue->attr_name_id]);
                }
            }

            if ($this->sku_desserts) {
                foreach ($this->sku_desserts as $value) {
                    if ($value['attr_data']) {
                        $sku = Sku::find()->where([
                            'and',
                            ['JSON EQ', 'attr_data', $value['attr_data']],
                            ['=', 'product_id', $this->id]
                        ])
                            ->one();
                        if (!$sku) {
                            $sku = new Sku();
                            $sku->product_id = $this->id;
                            $sku->attr_data = new JsonExpression($value['attr_data']);
                        }
                        $sku->price = $value['price'];
                        $sku->stock_num = $value['stock_num'];
                        $sku->save();
                    }
                }
            }
        }
    }
}
